import http from '@ohos.net.http'
import hilog from '@ohos.hilog'
import { Song } from '../model/Song'
import { Playlist } from '../model/Play'
import { Artist } from '../model/Artist'

// API基础URL
const BASE_URL = 'https://163api.qijieya.cn';

/**
 * 通用的GET请求函数
 * @param path 请求路径
 * @returns Promise<T> 异步返回请求结果
 */
async function get<T>(path: string): Promise<T> {
  const url = `${BASE_URL}${path}`
  const client = http.createHttp()
  try {
    const res = await client.request(url, {
      method: http.RequestMethod.GET,
      connectTimeout: 60_000 // 设置连接超时时间
    })
    hilog.info(0x0, 'API', `GET ${url} → ${res.responseCode}`)
    // 检查HTTP状态码
    if (res.responseCode < 200 || res.responseCode >= 300) {
      throw new Error(`HTTP ${res.responseCode}`)
    }
    // 解析JSON结果
    return JSON.parse(res.result as string) as T
  } finally {
    // 销毁HTTP客户端
    client.destroy()
  }
}

// 原始数据接口定义
interface RawArtist { name: string }
interface RawAlbum  { picUrl: string }
interface RawArtistInfo { id: number; name: string; picUrl: string; }

interface TopArtistsResp { artists: RawArtistInfo[]; }
interface RawSong {
  id: number
  name: string
  artists?: RawArtist[] // 艺术家列表
  ar?: RawArtist[] // 艺术家列表 (备用字段)
  album?: RawAlbum // 专辑信息
  al?: RawAlbum // 专辑信息 (备用字段)
}

interface RawCreator { nickname: string } // 创建者信息
interface RawPlaylistBase {
  id: number
  name: string
  picUrl: string // 封面图片URL
  trackCount: number // 曲目数量
  playCount: number // 播放次数
  creator?: RawCreator // 创建者
}

// API响应数据接口定义
interface SearchResp         { result: { songs: RawSong[] } } // 搜索响应
interface SongUrlResp        { data: { url: string }[] } // 歌曲URL响应
interface LyricResp          { lrc?: { lyric?: string } } // 歌词响应
interface NewSongResp        { result: { song?: RawSong }[] } // 新歌响应
interface SongDetailResp     { songs: RawSong[] } // 歌曲详情响应
interface PlaylistsResp      { result: RawPlaylistBase[] } // 歌单列表响应
interface PlaylistDetailResp { // 歌单详情响应
  playlist: {
    id: number
    name: string
    coverImgUrl: string // 封面图片URL
    trackCount: number // 曲目数量
    playCount: number // 播放次数
    tracks: RawSong[] // 曲目列表
  }
}
interface PlaylistTracksResp { songs: RawSong[]; more: boolean } // 歌单曲目分页响应

// 榜单和专辑相关接口定义
interface TopListResp         { playlist: { tracks: RawSong[] } } // 榜单详情响应
interface TopListAllResp      { list: { id: number; name: string; coverImgUrl: string }[] } // 所有榜单列表响应
interface NewAlbumsResp       { albums: RawAlbum[] } // 最新专辑响应
interface AlbumInfoResp       { album: { id: number; name: string; picUrl: string; artists: RawArtist[] } } // 专辑信息响应
interface ArtistTopSongsResp  { data: RawSong[] } // 歌手热门单曲响应
interface MvDetailResp        { data: { id: number; name: string; playCount: number; cover: string } } // MV详情响应

/**
 * 将http URL转换为https URL
 * @param url 原始URL
 * @returns https URL
 */
const https = (url: string): string => url.replace(/^http:/, 'https:')

/**
 * 将原始歌曲数据映射到Song模型
 * @param raw 原始歌曲数据
 * @returns Song模型
 */
function mapSong(raw: RawSong): Song {
  return {
    id: raw.id,
    name: raw.name,
    artist: (raw.artists ?? raw.ar ?? []).map(a => a.name).join(', '), // 提取艺术家名称并用逗号连接
    albumPic: https(raw.album?.picUrl ?? raw.al?.picUrl ?? '')
  }
}

/**
 * 将原始歌单数据映射到Playlist模型
 * @param raw 原始歌单数据
 * @returns Playlist模型
 */
function mapArtist(raw: RawArtistInfo): Artist {
  return {
    id: raw.id,
    name: raw.name,
    picUrl: https(raw.picUrl)
  }
}

function mapPlaylist(raw: RawPlaylistBase): Playlist {
  return {
    id: raw.id,
    name: raw.name,
    coverImgUrl: https(raw.picUrl), // 转换为https
    trackCount: raw.trackCount,
    playCount: raw.playCount
  }
}

/**
 * 搜索歌曲
 * @param keywords 搜索关键词
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function searchSongs(keywords: string): Promise<Song[]> {
  const d = await get<SearchResp>(`/search?keywords=${encodeURIComponent(keywords)}`)
  hilog.info(0x0, 'API', `Search results raw data: ${JSON.stringify(d)}`);
  return (d.result.songs ?? []).map(mapSong)
}

/**
 * 获取歌曲URL
 * @param id 歌曲ID
 * @returns Promise<string> 异步返回歌曲URL
 */
export async function getSongUrl(id: number): Promise<string> {
  const d = await get<SongUrlResp>(`/song/url?id=${id}`)
  return d.data[0]?.url ?? ''
}

/**
 * 获取歌词
 * @param id 歌曲ID
 * @returns Promise<string> 异步返回歌词内容
 */
export async function getLyric(id: number): Promise<string> {
  const d = await get<LyricResp>(`/lyric?id=${id}`)
  return d.lrc?.lyric ?? ''
}

/**
 * 获取推荐新歌
 * @param limit 限制数量
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function getRecommendSongs(limit = 30): Promise<Song[]> {
  const d = await get<NewSongResp>(`/personalized/newsong?limit=${limit}`)
  return d.result
    .map(item => mapSong(item.song ?? (item as unknown as RawSong)))
}

/**
 * 获取歌曲详情
 * @param id 歌曲ID
 * @returns Promise<Song> 异步返回歌曲详情
 */
export async function getSongDetail(id: number): Promise<Song> {
  const d = await get<SongDetailResp>(`/song/detail?ids=${id}`)
  const raw = d.songs[0]
  if (!raw) throw new Error('song not found')
  return mapSong(raw)
}


/**
 * 获取个性化推荐歌单
 * @param limit 限制数量
 * @returns Promise<Playlist[]> 异步返回歌单列表
 */
export async function getPersonalPlaylists(limit = 30): Promise<Playlist[]> {
  const d = await get<PlaylistsResp>(`/personalized?limit=${limit}`)
  return d.result.map(mapPlaylist)
}

/**
 * 获取歌单广场数据
 * @param limit 限制数量
 * @param offset 偏移量
 * @param cat 歌单分类
 * @returns Promise<{ playlists: Playlist[], total: number, more: boolean }> 异步返回歌单列表、总数和是否有更多
 */
export async function getPlaylistSquare(limit = 30, offset = 0, cat = '全部'): Promise<{
  playlists: Playlist[],
  total: number,
  more: boolean
}> {
  const d = await get<{
    playlists: RawPlaylistBase[],
    total: number,
    more: boolean
  }>(`/top/playlist?limit=${limit}&offset=${offset}&cat=${encodeURIComponent(cat)}`)
  return {
    playlists: d.playlists.map(mapPlaylist),
    total: d.total,
    more: d.more
  }
}

/**
 * 获取歌单详情（含首批曲目）
 * @param id 歌单ID
 * @returns Promise<{ info: Playlist, firstTracks: Song[] }> 异步返回歌单信息和首批曲目
 */
export async function getPlaylistDetail(id: number): Promise<{
  info: Playlist
  firstTracks: Song[]
}> {
  const d = await get<PlaylistDetailResp>(`/playlist/detail?id=${id}`)
  const pl = d.playlist
  return {
    info: {
      id: pl.id,
      name: pl.name,
      coverImgUrl: https(pl.coverImgUrl),
      trackCount: pl.trackCount,
      playCount: pl.playCount
    },
    firstTracks: pl.tracks.map(mapSong)
  }
}

/**
 * 分页获取歌单曲目
 * @param id 歌单ID
 * @param limit 限制数量
 * @param offset 偏移量
 * @returns Promise<{ songs: Song[]; more: boolean }> 异步返回歌曲列表和是否有更多
 */
export async function getPlaylistTracks(
  id: number,
  limit = 50,
  offset = 0
): Promise<{ songs: Song[]; more: boolean }> {
  const d = await get<PlaylistTracksResp>(
    `/playlist/track/all?id=${id}&limit=${limit}&offset=${offset}`
  )
  return { songs: d.songs.map(mapSong), more: d.more }
}

/**
 * 一次性拉取歌单所有曲目
 * @param id 歌单ID
 * @param pageSize 每页数量
 * @returns Promise<Song[]> 异步返回所有歌曲列表
 */
export async function fetchAllPlaylistTracks(
  id: number,
  pageSize = 50
): Promise<Song[]> {
  const all: Song[] = []
  let offset = 0
  let more = true
  while (more) {
    const { songs, more: m } = await getPlaylistTracks(id, pageSize, offset)
    all.push(...songs)
    offset += pageSize
    more = m
  }
  return all
}

/**
 * 获取随机歌曲
 * @returns Promise<Song | null> 异步返回随机歌曲或null
 */
export async function getRandomSong(): Promise<Song | null> {

  try {

    const topSongs = await getRecommendSongs(100);
    if (topSongs.length > 0) {
      const randomIndex = Math.floor(Math.random() * topSongs.length);
      return topSongs[randomIndex];
    } else {
      return null;
    }
    // --- End Placeholder Implementation ---

  } catch (error) {
    console.error('Error fetching random song:', error);
    return null;
  }
}

/* ──────────────────────── 7. "发现"页新增 API ──────────────────────── */
/**
 * 获取所有榜单列表
 * @returns Promise<{ id: number; name: string; coverImgUrl: string }[]> 异步返回榜单列表
 */
export async function getAllTopLists(): Promise<{ id: number; name: string; coverImgUrl: string }[]> {
  const d = await get<TopListAllResp>('/toplist')
  return d.list.map(item => ({
    id: item.id,
    name: item.name,
    coverImgUrl: https(item.coverImgUrl)
  }))
}

/**
 * 获取指定排行榜的曲目列表（如 idx=3778678: 热歌榜）
 * @param idx 榜单ID
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function getTopList(idx: number): Promise<Song[]> {
  const d = await get<TopListResp>(`/playlist/detail?id=${idx}`)
  return d.playlist.tracks.map(mapSong)
}

/**
 * 获取最新专辑封面列表
 * @param limit 限制数量
 * @returns Promise<string[]> 异步返回专辑封面URL列表
 */
export async function getNewestAlbums(limit = 10): Promise<string[]> {
  const d = await get<NewAlbumsResp>(`/album/newest?limit=${limit}`)
  return d.albums.map(a => https(a.picUrl))
}

/**
 * 获取专辑详情
 * @param id 专辑ID
 * @returns Promise<{ id: number; name: string; picUrl: string; artists: string[] }> 异步返回专辑详情
 */
export async function getAlbumInfo(id: number): Promise<{
  id: number
  name: string
  picUrl: string
  artists: string[]
}> {
  const d = await get<AlbumInfoResp>(`/album?id=${id}`)
  const a = d.album
  return {
    id: a.id,
    name: a.name,
    picUrl: https(a.picUrl),
    artists: a.artists.map(ar => ar.name)
  }
}

/**
 * 获取歌手热门单曲
 * @param id 歌手ID
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function getArtistTopSongs(id: number): Promise<Song[]> {
  const d = await get<ArtistTopSongsResp>(`/artist/top/song?id=${id}`)
  return d.data.map(mapSong)
}

/**
 * 获取歌手所有歌曲
 * @param id 歌手ID
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function getArtistSongs(id: number): Promise<Song[]> {
  const d = await get<{ songs: RawSong[] }>(`/artist/songs?id=${id}`);
  return d.songs.map(mapSong);
}

/**
 * 获取私人FM推荐歌曲
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function getPersonalFM(): Promise<Song[]> {
  const d = await get<{ data: RawSong[] }>('/personal_fm')
  return d.data.map(mapSong)
}

/**
 * 获取电台节目
 * @returns Promise<Song[]> 异步返回歌曲列表
 */
export async function getRadioPrograms(): Promise<Song[]> {
  const d = await get<{ programs: RawSong[] }>('/dj/program/recommend')
  return d.programs.map(mapSong)
}

/**
 * 获取 MV 详情
 * @param mvid MV ID
 * @returns Promise<{ id: number; name: string; playCount: number; cover: string }> 异步返回MV详情
 */
/**
 * 获取热门歌手
 * @param limit 限制数量
 * @returns Promise<Artist[]> 异步返回歌手列表
 */
export async function getTopArtists(limit = 30): Promise<Artist[]> {
  const d = await get<TopArtistsResp>(`/top/artists?limit=${limit}`)
  return d.artists.map(mapArtist)
}

export async function getMvDetail(mvid: number): Promise<{
  id: number
  name: string
  playCount: number
  cover: string
}> {
  const d = await get<MvDetailResp>(`/mv/detail?mvid=${mvid}`)
  const m = d.data
  return {
    id: m.id,
    name: m.name,
    playCount: m.playCount,
    cover: https(m.cover)
  }
}
